package com.gpj.learn.netty.reactor.masterslave;

import com.gpj.learn.netty.reactor.masterslave.handler.Acceptor;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.util.Iterator;
import java.util.Set;

/**
 * @className AcceptReactorServer
 * @description TODO
 * @author GPJ
 * @date 2020/5/15 17:04
 * @version 1.0
 **/
public class AcceptReactorServer implements Runnable{
    private ServerSocketChannel serverSocketChannel;
    private Selector selector;

    public AcceptReactorServer init(Integer port) throws IOException {
        serverSocketChannel = ServerSocketChannel.open();
        serverSocketChannel.configureBlocking(true);

        selector = Selector.open();
        SelectionKey register = serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
        register.attach(new Acceptor(serverSocketChannel, 8));

        serverSocketChannel.socket().bind(new InetSocketAddress(port));

        return this;
    }

    @Override
    public void run() {
        while (!Thread.interrupted()) {
            try {
                if (selector.select() == 0) {
                    continue;
                }
                Set<SelectionKey> selectionKeys = selector.selectedKeys();
                Iterator<SelectionKey> iterator = selectionKeys.iterator();
                while (iterator.hasNext()){
                    SelectionKey selectionKey = iterator.next();
                    if(selectionKey.isValid()){
                        Runnable acceptor = (Runnable) selectionKey.attachment();
                        if(acceptor != null) acceptor.run();

                        iterator.remove();
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}
